package com.dnjn.mes.biz.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.dnjn.mes.biz.domain.*;
import com.dnjn.mes.biz.mapper.MesWorkforceConfigMapper;
import com.dnjn.mes.biz.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.dnjn.mes.common.exception.job.TaskException;
import com.dnjn.mes.common.utils.DateUtils;
import com.dnjn.mes.quartz.domain.SysJob;
import com.dnjn.mes.quartz.service.ISysJobService;
import org.quartz.SchedulerException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.Objects;

import static com.dnjn.mes.common.utils.SecurityUtils.getUsername;

/**
 * <p>
 * 班次 服务实现类
 * </p>
 *
 * @author Amber
 * @since 2023-08-21
 */
@Service
public class MesWorkforceConfigServiceImpl extends ServiceImpl<MesWorkforceConfigMapper, MesWorkforceConfig> implements IMesWorkforceConfigService {
    @Autowired
    private IMesRecordCapacityService recordCapacityService;

    @Autowired
    private IMesRecordBeatService recordBeatService;

    @Autowired
    private IMesWorkforceXrefService workforceXrefService;

    @Autowired
    private IMesEquipmentService equipmentService;
    private static final Logger log = LoggerFactory.getLogger(MesWorkforceConfigServiceImpl.class);

    @Autowired
    private ISysJobService jobService;

    @Override
    public List<MesWorkforceConfig> getTrendsRecordCapacityCount(long equipmentId) {
        List<MesWorkforceConfig> workforceConfigList = getTrendsRecordCapacity(equipmentId);
        if (null == workforceConfigList || workforceConfigList.isEmpty()) {
            return null;
        }
        for (MesWorkforceConfig mesWorkforceConfig : workforceConfigList) {
            List<MesRecordCapacity> recordCapacityList = mesWorkforceConfig.getRecordCapacityList();
            if (recordCapacityList.isEmpty()) {
                mesWorkforceConfig.setTotalCapacity(0);
            } else {
                mesWorkforceConfig.setTotalCapacity(recordCapacityList.stream().filter(m -> !Objects.isNull(m.getCapacity())).mapToInt(MesRecordCapacity::getCapacity).sum());
            }
        }
        return workforceConfigList;
    }


    @Override
    public List<MesWorkforceConfig> getTrendsRecordCapacity(long equipmentId) {

        QueryWrapper<MesWorkforceConfig> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("deleted", "0");
        queryWrapper.eq("equipment_id", equipmentId);
        queryWrapper.orderByAsc("create_time");
        List<MesWorkforceConfig> workforceConfigList = baseMapper.selectList(queryWrapper);
        if (workforceConfigList.isEmpty()) {//没有早班晚班设置返回错误
            return null;
        }

        for (MesWorkforceConfig mesWorkforceConfig : workforceConfigList) {
            LocalTime startTime = mesWorkforceConfig.getStartTime();
            LocalTime endTime = mesWorkforceConfig.getEndTime();
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
            DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("HH:mm");
            String startLocalDateTime = formatter.format(LocalDateTime.now());
            String endLocalDateTime = formatter.format(LocalDateTime.now().plusDays(1));
            String time1;
            String time2;
            if (startTime.isBefore(endTime)) {//判断哪个是早班哪个是晚班
                //如果开始时间是凌晨八点之前的就是第二天的时间，如果是开始时间是凌晨八点之后（>=8）的就是今天的数据
                if (startTime.isBefore(LocalTime.parse("08:00", dateTimeFormatter))) {//明天凌晨的数据，传明天时间
                    time1 = endLocalDateTime + startTime.toString().split(":")[0];
                    time2 = endLocalDateTime + endTime.toString().split(":")[0];
                } else {//今天的数据，传今天时间
                    time1 = startLocalDateTime + startTime.toString().split(":")[0];
                    time2 = startLocalDateTime + endTime.toString().split(":")[0];
                }
            } else {//晚班 传今天和明天时间
                time1 = startLocalDateTime + startTime.toString().split(":")[0];
                time2 = endLocalDateTime + endTime.toString().split(":")[0];
            }
            List<MesRecordCapacity> list = recordCapacityService.getEarlyTrendsCapacityByTime(equipmentId, startTime, endTime, time1, time2);
            mesWorkforceConfig.setRecordCapacityList(list);
        }
        return workforceConfigList;
    }

    @Override
    public List<MesWorkforceConfig> getTrendsRecordBeatChart(long equipmentId) {
        QueryWrapper<MesWorkforceConfig> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("deleted", "0");
        queryWrapper.eq("equipment_id", equipmentId);
        queryWrapper.orderByAsc("create_time");
        List<MesWorkforceConfig> workforceConfigList = baseMapper.selectList(queryWrapper);
        if (workforceConfigList.isEmpty()) {//没有早班晚班设置返回错误
            return null;
        }

        for (MesWorkforceConfig mesWorkforceConfig : workforceConfigList) {
            LocalTime startTime = mesWorkforceConfig.getStartTime();
            LocalTime endTime = mesWorkforceConfig.getEndTime();
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
            DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("HH:mm");
            String startLocalDateTime = formatter.format(LocalDateTime.now());
            String endLocalDateTime = formatter.format(LocalDateTime.now().plusDays(1));
            String time1;
            String time2;
            if (startTime.isBefore(endTime)) {//早班
                //如果开始时间是凌晨八点之前的就是第二天的时间，如果是开始时间是凌晨八点之后（>=8）的就是今天的数据
                if (startTime.isBefore(LocalTime.parse("08:00", dateTimeFormatter))) {//明天凌晨的数据，传明天时间
                    time1 = endLocalDateTime + " " + startTime.toString() + ":00";
                    time2 = endLocalDateTime + " " + endTime.toString() + ":00";
                } else {//今天的数据，传今天时间
                    time1 = startLocalDateTime + " " + startTime.toString() + ":00";
                    time2 = startLocalDateTime + " " + endTime.toString() + ":00";
                }
            } else {//晚班 传今天和明天时间
                time1 = startLocalDateTime + " " + startTime.toString() + ":00";
                time2 = endLocalDateTime + " " + endTime.toString() + ":00";
            }
            List<MesRecordBeat> list = recordBeatService.getTrendsRecordBeatChart(equipmentId, startTime, endTime, time1, time2);
            mesWorkforceConfig.setRecordBeatList(list);
        }

        return workforceConfigList;
    }

    @Override
    @Transactional
    public boolean saveWorkforceConfig(MesWorkforceConfig domain) {
        MesEquipment mesEquipment = equipmentService.fetchCurrent();
        Long equipmentId = mesEquipment.getEquipmentId();
        try {
            //判重
           /* Long count = baseMapper.selectCount(Wrappers.<MesWorkforceConfig>lambdaQuery()
                    .eq(MesWorkforceConfig::getWorkforceName, domain.getWorkforceName())
                    .eq(MesWorkforceConfig::getStartTime, domain.getStartTime()).eq(MesWorkforceConfig::getEndTime, domain.getEndTime()).eq(MesWorkforceConfig::getDeleted,"0"));
            if (count > 0) {
                return false;
            }*/
            //校验时间范围是否重复
            List<MesWorkforceConfig> mesWorkforceConfigList = baseMapper.selectList(new QueryWrapper<MesWorkforceConfig>().eq("deleted", "0").eq("equipment_id",equipmentId));
            for (MesWorkforceConfig mesWorkforceConfig : mesWorkforceConfigList) {
                String startTime = domain.getStartTime().toString();
                String endTime = domain.getEndTime().toString();
                String s1 = mesWorkforceConfig.getStartTime().toString();
                String s2 = mesWorkforceConfig.getEndTime().toString();
                if (s1.equals(startTime) || s2.equals(endTime)) {
                    throw new Exception();
                }
                if (DateUtils.isInTimeRange(startTime, s1, s2) || DateUtils.isInTimeRange(endTime, s1, s2)) {
                    throw new Exception();
                }
            }
            domain.setEquipmentId(equipmentId);
            baseMapper.insert(domain);
            List<MesWorkforceXref> workforceXrefList = domain.getWorkforceXrefList();
            if (workforceXrefList != null && workforceXrefList.size() > 0) {
                for (MesWorkforceXref mesWorkforceXref : workforceXrefList) {
                    mesWorkforceXref.setWorkforceId(domain.getWorkforceId());
                    //mesWorkforceXref.setCreateBy(getUsername());
                    workforceXrefService.save(mesWorkforceXref);
                }
            }
            //根据开始时间前20分钟动态生成job    0 30 2 * * ? 每天两点三十执行
            beginTime(domain,equipmentId);

            //根据结束时间后20分钟动态生成job    0 30 2 * * ? 每天两点三十执行
            //endTime(domain);


        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

    private void endTime(MesWorkforceConfig domain) throws SchedulerException, TaskException {
        //根据结束时间后20分钟动态生成job    0 30 2 * * ? 每天两点三十执行
        LocalTime endTime = domain.getEndTime().plusMinutes(20);
        String s = endTime.toString(); //
        String[] split = s.split(":");
        String s1 = split[0];
        if (s1.startsWith("0")) {
            s1 = s1.substring(1);
        }
        String s2 = split[1];
        if (s2.startsWith("0")) {
            s2 = s2.substring(1);
        }
        String cronStr = "0" + " " + s2 + " " + s1 + " * * ?";
        SysJob job = new SysJob();
        job.setJobGroup("workforce");
        job.setJobName("workforceEnd" + domain.getWorkforceId().toString());
        job.setCronExpression(cronStr);
        job.setInvokeTarget("workforceTask.handleWorkforceshiftEnd('" + domain.getEndTime().toString() + "')");
//            job.setInvokeTarget("workforceTask.handleWorkforceshift");
        job.setCreateBy(getUsername());
        job.setMisfirePolicy("3");
        job.setStatus("0");
        jobService.insertJob(job);
        SysJob newJob = jobService.selectJobById(job.getJobId());
        newJob.setStatus("0");
        jobService.changeStatus(newJob);
    }

    private void beginTime(MesWorkforceConfig domain,Long equipmentId) throws SchedulerException, TaskException {
        LocalTime startTime = domain.getStartTime().minusMinutes(20);
        String s = startTime.toString(); // 7:40  19:20
        String[] split = s.split(":");
        String s1 = split[0];
        if (s1.startsWith("0")) {
            s1 = s1.substring(1);
        }
        String s2 = split[1];
        if (s2.startsWith("0")) {
            s2 = s2.substring(1);
        }
        String cronStr = "0" + " " + s2 + " " + s1 + " * * ?";
        SysJob job = new SysJob();
        job.setJobGroup("workforce");
        job.setJobName("workforceBegin" + domain.getWorkforceId().toString());
        job.setCronExpression(cronStr);
//        job.setInvokeTarget("workforceTask.handleWorkforceshift('" + domain.getStartTime().toString());
//        job.setInvokeTarget("workforceTask.handleWorkforceshift('" + domain.getStartTime().toString() + "' , "+ equipmentId +")");
        job.setInvokeTarget("workforceTask.handleWorkforceshift('" + domain.getStartTime().toString() + "' , '"+ equipmentId +"')");

//            job.setInvokeTarget("workforceTask.handleWorkforceshift");
        job.setCreateBy(getUsername());
        job.setMisfirePolicy("3");
        job.setStatus("0");
        jobService.insertJob(job);
        SysJob newJob = jobService.selectJobById(job.getJobId());
        newJob.setStatus("0");
        jobService.changeStatus(newJob);
    }

    @Override
    @Transactional
    public boolean updateWorkforceConfig(MesWorkforceConfig domain) {
        try {
            //校验时间范围是否重复
            QueryWrapper<MesWorkforceConfig> queryWrapper1 = new QueryWrapper<>();
            List<MesWorkforceConfig> mesWorkforceConfigList = baseMapper.selectList(queryWrapper1.eq("deleted", "0"));
            for (MesWorkforceConfig mesWorkforceConfig : mesWorkforceConfigList) {
                String startTime = domain.getStartTime().toString();
                String endTime = domain.getEndTime().toString();
                String s1 = mesWorkforceConfig.getStartTime().toString();
                String s2 = mesWorkforceConfig.getEndTime().toString();
                Long workforceId = mesWorkforceConfig.getWorkforceId();
                Long workforceId1 = domain.getWorkforceId();
                if (!workforceId.equals(workforceId1)) {
                    if (s1.equals(startTime) || s2.equals(endTime)) {
                        throw new Exception();
                    }
                    if (DateUtils.isInTimeRange(startTime, s1, s2) || DateUtils.isInTimeRange(endTime, s1, s2)) {
                        throw new Exception();
                    }
                } else {

                }

            }
            //修改班次
            int i = baseMapper.updateById(domain);
            /*if (i <= 0) {
                return false;
            }*/
            //先删除关联用户
            QueryWrapper<MesWorkforceXref> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("workforce_id", domain.getWorkforceId());
            workforceXrefService.remove(queryWrapper);
            //新增关联用户
            List<MesWorkforceXref> workforceXrefList = domain.getWorkforceXrefList();
            if (workforceXrefList != null && workforceXrefList.size() > 0) {
                for (MesWorkforceXref mesWorkforceXref : workforceXrefList) {
                    mesWorkforceXref.setWorkforceId(domain.getWorkforceId());
                    //mesWorkforceXref.setCreateBy(getUsername());
                    workforceXrefService.save(mesWorkforceXref);
                }
            }

            updateBeginTime(domain, domain.getEquipmentId());

            //updateEndTime(domain);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

    private void updateEndTime(MesWorkforceConfig domain) throws SchedulerException, TaskException {
        //更新job表的cron表达式
        SysJob job = new SysJob();
        job.setJobName("workforceEnd" + domain.getWorkforceId().toString());
        job = jobService.selectJobList(job).get(0);

        LocalTime endTime = domain.getEndTime().plusMinutes(20);
        String s = endTime.toString(); // 8:00  8:20
        String[] split = s.split(":");
        String s1 = split[0];
        if (s1.startsWith("0")) {
            s1 = s1.substring(0);
        }
        String s2 = split[1];
        if (s2.startsWith("0")) {
            s2 = s2.substring(0);
        }
        String cronStr = "0" + " " + s2 + " " + s1 + " * * ?";
        job.setCronExpression(cronStr);
        job.setInvokeTarget("workforceTask.handleWorkforceshift('" + domain.getEndTime().toString() + "')");
//            job.setInvokeTarget("workforceTask.handleWorkforceshift");
        job.setStatus("0");
        jobService.updateJob(job);
    }

    private void updateBeginTime(MesWorkforceConfig domain,Long equipmentId) throws SchedulerException, TaskException {
        //更新job表的cron表达式
        SysJob job = new SysJob();
        job.setJobName("workforceBegin" + domain.getWorkforceId().toString());
        job = jobService.selectJobList(job).get(0);
        LocalTime startTime = domain.getStartTime().minusMinutes(20);
        String s = startTime.toString(); // 7:40  19:20
        String[] split = s.split(":");
        String s1 = split[0];
        if (s1.startsWith("0")) {
            s1 = s1.substring(0);
        }
        String s2 = split[1];
        if (s2.startsWith("0")) {
            s2 = s2.substring(0);
        }
        String cronStr = "0" + " " + s2 + " " + s1 + " * * ?";
        job.setCronExpression(cronStr);
//        job.setInvokeTarget("workforceTask.handleWorkforceshift('" + domain.getStartTime().toString() + "')");
        job.setInvokeTarget("workforceTask.handleWorkforceshift('" + domain.getStartTime().toString() + "' , '"+ equipmentId +"')");

//            job.setInvokeTarget("workforceTask.handleWorkforceshift");
        job.setStatus("0");
        jobService.updateJob(job);
    }

    @Override
    @Transactional
    public Boolean removeWorkforceConfigByIds(Long pkId) {
        //软删除？
        try {
            MesWorkforceConfig mesWorkforceConfig = new MesWorkforceConfig();
            mesWorkforceConfig.setWorkforceId(pkId);
            mesWorkforceConfig.setDeleted("1");
            baseMapper.updateById(mesWorkforceConfig);
            //同步删除班次关联用户
            QueryWrapper<MesWorkforceXref> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("workforce_id", pkId);
            workforceXrefService.remove(queryWrapper);
            //删除关联的job定时任务
            SysJob job = new SysJob();
            job.setJobName("workforceBegin" + pkId);
            List<SysJob> sysJobs = jobService.selectJobList(job);
            if (null != sysJobs && sysJobs.size() > 0) {
                job = sysJobs.get(0);
                jobService.deleteJob(job);
            }
            /*SysJob job1 = new SysJob();
            job1.setJobName("workforceEnd" + pkId);
            List<SysJob> sysJobs1 = jobService.selectJobList(job1);
            if (null != sysJobs1 && sysJobs1.size() > 0) {
                job1 = sysJobs1.get(0);
                jobService.deleteJob(job1);
            }*/
        } catch (Exception e) {
            log.error("删除班次失败");
            return false;
        }
        return true;
    }

    @Override
    public List<MesRecordBeat> getIndexRecordBeatChart(long equipmentId) {
        return baseMapper.getIndexRecordBeatChart(equipmentId);
    }
}